package com.qsdjf.fp.weixin.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qsdjf.fp.weixin.configuration.properties.Config;
import com.qsdjf.fp.weixin.model.TextOpenId;

@Controller
public class WeixinController {

	private Logger logger = LoggerFactory.getLogger(WeixinController.class);

	@Autowired
	private Config config;

	/**
	 * 微信公众平台开发者文档地址：http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html 参见：【用户管理】【网页授权获取用户基本信息】模块
	 * 第一步：用户同意授权，获取code
	 * 
	 * @param mpName
	 * @param returnUrl
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws
	 * @throws NoSuchFieldException
	 */
	@RequestMapping(value = "/openid", method = RequestMethod.GET)
	public String getOpenid(String returnUrl) throws UnsupportedEncodingException, NoSuchFieldException,
			IllegalArgumentException, IllegalAccessException {
		logger.debug("引导用户用微信客户端打开的链接");
		/**
		 * 引导用户用微信客户端打开的链接，以获取 code
		 */
		String redirectUrlOpenInWeixin = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";

		redirectUrlOpenInWeixin = redirectUrlOpenInWeixin.replace("APPID", config.getAppid());
		redirectUrlOpenInWeixin = redirectUrlOpenInWeixin.replace("REDIRECT_URI",
				URLEncoder.encode(config.getRedirectUri() + "?returnUrl=" + returnUrl, "utf-8"));
		// 这里根据需求填 snsapi_userinfo || snsapi_base ，具体含义见微信公众平台开发者文档
		redirectUrlOpenInWeixin = redirectUrlOpenInWeixin.replace("SCOPE", "snsapi_base");

		// 这一步是向微信支付系统发出请求
		return "redirect:" + redirectUrlOpenInWeixin;
	}

	/**
	 * 第二步：通过code换取网页授权access_token
	 * 
	 * @param code
	 * @param state
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	@RequestMapping(value = "/accessToken", method = RequestMethod.GET)
	public String accessToken(String code, String state, String returnUrl) throws ClientProtocolException, IOException {
		// code 作为换取 access_token 的票据，每次用户授权带上的 code 将不一样， code 只能使用一次， 5 分钟未被使用自动过期。
		String getAccessTokenByCode = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
		getAccessTokenByCode = getAccessTokenByCode.replace("APPID", config.getAppid());
		getAccessTokenByCode = getAccessTokenByCode.replace("SECRET", config.getAppsecret());
		getAccessTokenByCode = getAccessTokenByCode.replace("CODE", code);

		// 向微信服务器发起获取 access_token 的请求
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpGet httpGet = new HttpGet(getAccessTokenByCode);
		CloseableHttpResponse response = httpclient.execute(httpGet);
		String responseStr = EntityUtils.toString(response.getEntity());
		ObjectMapper objectMapper = new ObjectMapper();
		TextOpenId textOpenId = objectMapper.readValue(responseStr, new TypeReference<TextOpenId>() {
		});
		logger.debug("Openid\t" + textOpenId.getOpenid());

		returnUrl = returnUrl + "&openid=" + textOpenId.getOpenid();
		return "redirect:" + returnUrl;
	}

}
